package com.okbihuo.perm.core.auth.jwt;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.util.*;

/**
 * jwt 辅助
 */
@Component
public class JwtHelper implements Serializable {
    private static final long serialVersionUID = -2550185165626007488L;

    public static String HEADER = "Authorization";
    public static String ACCESS_TOKEN_PARAM = "access_token";
    public static String BASIC_HEADER_PREFIX = "Basic ";
    public static String SIGN_KEY = "perm";
    // 5 小时
    public static long EXPIRES = 18000000;
    public static String[] allowWhiteList;

    @Value("${jwt.header:Authorization}")
    public void setHeader(String Header) {
        JwtHelper.HEADER = HEADER;
    }

    @Value("${jwt.access-token-param:access_token}")
    public void setAccessTokenParam(String accessTokenParam) {
        ACCESS_TOKEN_PARAM = accessTokenParam;
    }

    @Value("${jwt.basic-header-prefix:Basic}")
    public void setBasicHeaderPrefix(String basicHeaderPrefix) {
        BASIC_HEADER_PREFIX = basicHeaderPrefix;
    }

    @Value("${jwt.sign-key:perm}")
    public void setSignKey(String signKey) {
        SIGN_KEY = signKey;
    }

    @Value("${jwt.expires:18000000}")
    public void setEXPIRES(Long expires) {
        EXPIRES = expires;
    }
    @Value("${jwt.allow-white-list:/open/**,/login/**}")
    public void setAllowWhiteList(String[] array) {
        allowWhiteList = array;
    }
    /**
     * 根据用户生成token
     */
    public static String generateToken(UserDetails userDetails) {
        Map<String, Object> claims = new HashMap<>();
        return doGenerateToken(claims, userDetails.getUsername());
    }

    private static String doGenerateToken(Map<String, Object> claims, String subject) {
        long l = System.currentTimeMillis();
        Date now = new Date(l);
        Date expiration = new Date(l + EXPIRES);
        return Jwts.builder()
                .setClaims(claims)
                .setSubject(subject)
                .setIssuedAt(now)
                .setExpiration(expiration)
                .signWith(SignatureAlgorithm.HS512, SIGN_KEY).compact();
    }

    /**
     * 验证token是否过期
     */
    public static Boolean isTokenExpired(String token) {
        final Date expiration = getExpirationDateFromToken(token);
        return expiration.before(new Date());
    }

    //通过token得到token过期时间
    private static Date getExpirationDateFromToken(String token) {
        return getClaimsFromToken(token).getExpiration();
    }

    /**
     * 解析token
     */
    public static Claims getClaimsFromToken(String token) {
        return Jwts.parser().setSigningKey(SIGN_KEY).parseClaimsJws(token).getBody();
    }


    //验证token

    /**
     * 验证token是否仍然有效
     */
    public static boolean validateToken(String token) {
        return !isTokenExpired(token);
    }
}
